package com.equipment.management.util;

import com.equipment.management.dao.MainframeDao;
import com.equipment.management.entity.HandleTimer;
import com.equipment.management.service.MainframeService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Liuxd on 2018-11-02.
 */
@Slf4j
public class Base64Util {

    @Value("${spring.mqtt.username}")
    private String username;

    @Value("${spring.mqtt.password}")
    private String password;

    @Value("${spring.mqtt.url}")
    private String hostUrl;

    @Value("${spring.mqtt.client.id}")
    private String clientId;

    @Value("${spring.mqtt.default.topic}")
    private String defaultTopic;

    @Value("${spring.mqtt.completionTimeout}")
    private int completionTimeout ;   //连接超时

    @Value("${spring.mqtt.client.id}")
    private String randomid ;   //连接超时

    @Autowired
    private MainframeService mainframeService;

    @Autowired
    private MainframeDao mainframeDao;//这里会报错，但是并不会影响


    private MqttClient client=null;
    public static void main(String[] args) throws Exception {
        String str = "wang19941121";

        base64(str);

        enAndDeCode(str);

    }




    public  void publish(String topic) throws MqttException{

        client =new MqttClient(hostUrl,clientId);
        MqttConnectOptions connectOptions=new MqttConnectOptions();
        connectOptions.setCleanSession(true);
        connectOptions.setUserName(username);
        connectOptions.setPassword(password.toCharArray());
        client.connect(connectOptions);
        MqttMessage message=new MqttMessage(topic.getBytes());
        message.setQos(1);
        client.publish(topic,message);
//        client.disconnect();
//        client.close();
    }



    public   void subscribe(String topic, String operate, String random) throws MqttException {


        int counts=mainframeDao.getTimerbyrandom(random);
        if(counts==0){
            HandleTimer m=new HandleTimer();
            m.setId(Integer.valueOf(random));
            m.setCreate_time(new Date());

            //获取当前日期
            SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );
            Date today = new Date();
            String endDate = sdf .format( today ); //当前日期
            //获取三十天前日期
            Calendar theCa = Calendar. getInstance ();
            theCa .setTime( today );
            theCa .add( theCa . MINUTE , 2); //最后一个数字30可改，30天的意思
            theCa.add(theCa.SECOND,30);
            Date start = theCa .getTime();
            m.setEnd_time(start);
            mainframeDao.insertTimer(m);
        }


        MemoryPersistence persistence=new MemoryPersistence();
        client=new MqttClient(hostUrl,randomid,persistence);
        MqttConnectOptions connectOptions=new MqttConnectOptions();
        connectOptions.setCleanSession(true);
        connectOptions.setUserName(username);
        connectOptions.setPassword(password.toCharArray());
        client.connect(connectOptions);

        client.setCallback(new MqttCallback() {
            public void connectionLost(Throwable throwable) {
            }
            public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                log.info("topic:{},operate:{},mqttMessage:{}",topic,operate,mqttMessage);
                try {
                    if (mqttMessage != null) {
                        log.info("接收到的消息体:{}", new String(mqttMessage.getPayload(), "UTF-8"));
                        //查询本次消息是否过期
                        int counts=mainframeDao.getTimer(random);

                        String payload = new String(mqttMessage.getPayload(), "UTF-8");
                        if (payload.contains("#index")) {
                            //操作类型
                            String type = payload.substring(0, payload.indexOf("#index"));
                            //5位随机数,以便保证是同一次初始化或者扫描
                            // String sum=payload.substring(0,5);
                            //    if(random.equals(sum)){

                            int numm = Integer.valueOf(payload.substring(payload.indexOf("#index:"),payload.indexOf("|")).substring(7));
                            if(numm>50000){
                                return;
                            }

                            payload = payload.substring(payload.indexOf("|") + 1);
                            String[] paraStr = payload.split("\\|");

                            List<String> list = new ArrayList<>();
                            list.add(paraStr[0]);
                            //list.add(paraStr[1]);

                            log.info("type:{},message:{}", type, list);
                            topic = topic.replace("device_pub:", "");
                            topic = topic.replace("device_sub:", "");

                            //初始化
                            if ("init".equals(type)&&counts>0) {
                                mainframeService.updateInitMainframe(topic, list, operate, random);
                            } else if ("scan".equals(type)&&counts>0) {//扫描
                                mainframeService.updateMainframeResult(topic, payload, operate, list, random);
                            } else if ("close".equals(type)) {//扫描
                                mainframeService.closeMainframeResult(topic, operate);
                            }
                            //}
                        }
                    } else {

                        mainframeService.updateMainframeResult(topic, null, operate, null, random);

                    }
                }catch (Exception e){
                    log.info("接收消息异常:{}",e);
                }

            }
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

                System.out.println("发送成功");
            }
        });
        client.subscribe(topic,1);
//        client.disconnect();
//        client.close();
    }

    public String  random(){
        String sources = "0123456789"; // 加上一些字母，就可以生成pc站的验证码了
        Random rand = new Random();
        StringBuffer flag = new StringBuffer();
        for (int j = 0; j < 5; j++)
        {
            flag.append(sources.charAt(rand.nextInt(9)) + "");
        }
        System.out.println(flag.toString());
        return flag.toString();
    }




    /**
     * Base64
     *
     */
    public static void base64(String str) {
        byte[] bytes = str.getBytes();

        //Base64 加密
        String encoded = Base64.getEncoder().encodeToString(bytes);
        System.out.println("Base 64 加密后：" + encoded);

        //Base64 解密
        byte[] decoded = Base64.getDecoder().decode(encoded);

        String decodeStr = new String(decoded);
        System.out.println("Base 64 解密后：" + decodeStr);

    }


    /**
     * BASE64加密
     */
    public static String encrypt(String str) throws Exception {
        String data = encryptBASE64(str.getBytes());
        System.out.println("sun.misc.BASE64 加密后：" + data);
        return  data;
    }


    /**
     * BASE64解密
     */
    public static String decryption(String str) throws Exception {
        //Base64 解密
        byte[] decoded = Base64.getDecoder().decode(str);

        String decodeStr = new String(decoded);
        System.out.println("Base 64 解密后：" + decodeStr);
        return  decodeStr;
    }

    /**
     * BASE64加密解密
     */
    public static void enAndDeCode(String str) throws Exception {
        String data = encryptBASE64(str.getBytes());
        System.out.println("sun.misc.BASE64 加密后：" + data);

        byte[] byteArray = decryptBASE64(data);
        System.out.println("sun.misc.BASE64 解密后：" + new String(byteArray));
    }

    /**
     * BASE64解密
     * @throws Exception
     */
    public static byte[] decryptBASE64(String key) throws Exception {
        return (new BASE64Decoder()).decodeBuffer(key);
    }

    /**
     * BASE64加密
     */
    public static String encryptBASE64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(key);
    }




}